package com.boc;

import java.io.*;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.regex.*;

public class IBatisToMyBatisConverter {
    public static void main(String[] args) throws IOException {
        String inputFilePath = "ibatis.xml"; // 输入文件路径
        String outputFilePath = "mybatis.xml"; // 输出文件路径

        // 读取 XML 文件内容
        String xmlContent = Files.readString(Paths.get(inputFilePath), StandardCharsets.UTF_8);

        // 移除现有文件头并转换内容
        String cleanedContent = removeFileHeader(xmlContent);
        String convertedContent = convertIBatisToMyBatis(cleanedContent);

        // 替换 <sqlMap> 为 <mapper> 并修改 namespace
        convertedContent = replaceSqlMapWithMapper(convertedContent);

        // 替换结尾的 </sqlMap> 为 </mapper>
        convertedContent = convertedContent.replaceAll("</sqlMap>", "</mapper>");

        // 处理 resultMap 标签中的 class 属性替换为 type
        convertedContent = replaceResultMapClassWithType(convertedContent);

        // 处理 parameterClass 属性替换为 parameterType
        convertedContent = replaceParameterClassWithParameterType(convertedContent);

        // 在转换后的内容之前添加新的文件头
        String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n";

        // 将文件头和转换后的内容合并
        String finalContent = header + convertedContent;

        // 将文件头和转换后的内容写入文件
        Files.writeString(Paths.get(outputFilePath), finalContent, StandardCharsets.UTF_8);

        System.out.println("Conversion completed! Output saved to " + outputFilePath);
    }

    // 移除现有的文件头
    private static String removeFileHeader(String xmlContent) {
        // 正则匹配 XML 文件头部分
        String headerPattern = "^<\\?xml[\\s\\S]*?\\?>\\s*<!DOCTYPE[\\s\\S]*?\\s*>\\s*";
        return xmlContent.replaceAll(headerPattern, "");
    }

    // 替换 <sqlMap> 为 <mapper> 并修改 namespace
    private static String replaceSqlMapWithMapper(String xmlContent) {
        // 正则匹配 <sqlMap> 标签并提取 namespace 属性
        Pattern sqlMapPattern = Pattern.compile("<sqlMap\\s+namespace=\"([^\"]+)\"[^>]*>", Pattern.DOTALL);
        Matcher matcher = sqlMapPattern.matcher(xmlContent);

        // 替换每一个 <sqlMap> 标签
        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            // 获取原始 namespace 值
            String originalNamespace = matcher.group(1);

            // 去掉 sql_ 前缀并修改 namespace
            String newNamespace = "com.bocsoft.csar.sts.application.bootstrap.mapper.csar." +
                    originalNamespace.replace("sql_", "") + "Dao";

            // 替换为新的 <mapper> 标签
            String newSqlMapTag = "<mapper namespace=\"" + newNamespace + "\">";
            matcher.appendReplacement(result, Matcher.quoteReplacement(newSqlMapTag));
        }
        matcher.appendTail(result);

        return result.toString();
    }

    // 替换 resultMap 中的 class 属性为 type
    private static String replaceResultMapClassWithType(String xmlContent) {
        // 正则匹配 <resultMap> 标签并提取 class 属性
        Pattern resultMapPattern = Pattern.compile(
                "<resultMap\\s+[^>]*class=\"([^\"]+)\"[^>]*>", Pattern.DOTALL);
        Matcher matcher = resultMapPattern.matcher(xmlContent);

        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            // 获取原始 class 值
            String className = matcher.group(1);

            // 提取 className 中最后的部分（去掉包名）
            String baseName = className.substring(className.lastIndexOf('.') + 1);

            // 构建新的 type 值
            String newType = "com.bocsoft.csar.sts.application.bootstrap.entity.csar." + baseName;

            // 替换 class 属性为 type，并修改其值
            String newResultMapTag = matcher.group(0).replace("class=\"" + className + "\"", "type=\"" + newType + "\"");
            matcher.appendReplacement(result, Matcher.quoteReplacement(newResultMapTag));
        }
        matcher.appendTail(result);

        return result.toString();
    }

    // 替换 parameterClass 属性为 parameterType
    // 替换 parameterClass 属性为 parameterType
    private static String replaceParameterClassWithParameterType(String xmlContent) {
        // 正则匹配带有 parameterClass 属性的标签，适应多种标签情况
        Pattern parameterClassPattern = Pattern.compile(
                "<(\\w+)([^>]*?)parameterClass=\"([^\"]+)\"([^>]*?)>", Pattern.DOTALL);
        Matcher matcher = parameterClassPattern.matcher(xmlContent);

        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            // 提取标签名、属性值和其他属性
            String tagName = matcher.group(1); // 标签名
            String beforeParamClass = matcher.group(2); // 参数前部分
            String parameterClassValue = matcher.group(3); // parameterClass 属性值
            String afterParamClass = matcher.group(4); // 参数后部分

            // 替换为 parameterType
            String newTag = String.format("<%s%sparameterType=\"%s\"%s>",
                    tagName, beforeParamClass, parameterClassValue, afterParamClass);

            matcher.appendReplacement(result, Matcher.quoteReplacement(newTag));
        }
        matcher.appendTail(result);

        return result.toString();
    }


    private static String convertIBatisToMyBatis(String xmlContent) {
        // 替换占位符 #property# 为 #{property}
        xmlContent = xmlContent.replaceAll("#(\\w+)#", "#{$1}");

        // 正则匹配 <isNotEmpty> 标签，注意顺序是 prepend 在前，property 在后
        Pattern isNotEmptyPattern = Pattern.compile(
                "<isNotEmpty\\s+prepend=\"([^\"]+)\"\\s+property=\"([^\"]+)\"\\s*>(.*?)</isNotEmpty>",
                Pattern.DOTALL
        );

        Matcher matcher = isNotEmptyPattern.matcher(xmlContent);
        StringBuffer result = new StringBuffer();

        // 替换 <isNotEmpty> 为 <if>
        while (matcher.find()) {
            String prepend = matcher.group(1); // 提取 prepend 属性
            String property = matcher.group(2); // 提取 property 属性
            String content = matcher.group(3).trim(); // 提取标签内部内容

            // 构造 <if> 标签
            String ifTag = String.format("<if test=\"%s != null and %s != ''\">%s %s</if>",
                    property, property, prepend != null ? prepend : "", content);

            // 替换内容
            matcher.appendReplacement(result, Matcher.quoteReplacement(ifTag));
        }
        matcher.appendTail(result);

        return result.toString();
    }
}
